home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / fips11.zip / SOURCE / DISK_IO.CPP < prev    next >
C/C++ Source or Header  |  1994-05-25  |  7KB  |  205 lines

  1. /*
  2.     FIPS - the First nondestructive Interactive Partition Splitting program
  3.  
  4.     Module disk_io.cpp
  5.  
  6.     RCS - Header:
  7.     $Header: c:/daten/fips/source/main/RCS/disk_io.cpp 1.1 1994/05/25 22:19:43 schaefer Exp schaefer $
  8.  
  9.     Copyright (C) 1993 Arno Schaefer
  10.  
  11.     This program is free software; you can redistribute it and/or modify
  12.     it under the terms of the GNU General Public License as published by
  13.     the Free Software Foundation; either version 2 of the License, or
  14.     (at your option) any later version.
  15.  
  16.     This program is distributed in the hope that it will be useful,
  17.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.     GNU General Public License for more details.
  20.  
  21.     You should have received a copy of the GNU General Public License
  22.     along with this program; if not, write to the Free Software
  23.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  
  25.  
  26.     Report problems and direct all questions to:
  27.  
  28.     schaefer@rbg.informatik.th-darmstadt.de
  29. */
  30.  
  31. #include "disk_io.h"
  32. #include <dos.h>
  33. #include <bios.h>
  34.  
  35. #define DISK_INT 0x13
  36.  
  37. #define RESET_DISK 0
  38. #define READ_SECTOR 2
  39. #define WRITE_SECTOR 3
  40. #define VERIFY_SECTOR 4
  41. #define GET_DRIVE_PARAMS 8
  42. #define GET_DISK_TYPE 0x15
  43.  
  44. /* ----------------------------------------------------------------------- */
  45. /* Bios call to get the number of drives attached                          */
  46. /* ----------------------------------------------------------------------- */
  47.  
  48. int get_no_of_drives (void)
  49. {
  50.     union REGS regs;
  51.  
  52.     regs.h.ah = GET_DRIVE_PARAMS;
  53.     regs.h.dl = 0x80;
  54.     int86 (DISK_INT,®s,®s);
  55.     if (regs.h.ah != 0) return (1); // will be checked again
  56.     return (regs.h.dl);
  57. }
  58.  
  59. /* ----------------------------------------------------------------------- */
  60. /* Calculates physical sector number (Head, Cylinder, Sector).             */
  61. /* Log_sector is absolute logical sector number (0 = master boot record).  */
  62. /* ----------------------------------------------------------------------- */
  63.  
  64. physical_sector_no::physical_sector_no (dword log_sector,const drive_geometry &geometry)
  65. {
  66.     cylinder = log_sector / (geometry.heads * geometry.sectors);
  67.     head = (log_sector - (cylinder * geometry.heads * geometry.sectors)) / geometry.sectors;
  68.     sector = log_sector - (cylinder * geometry.heads * geometry.sectors) - (head * geometry.sectors) + 1;
  69. }
  70.  
  71. /* ----------------------------------------------------------------------- */
  72. /* Bios call get_drive_geometry, returns error status in var errorcode     */
  73. /* ----------------------------------------------------------------------- */
  74.  
  75. void physical_drive::get_geometry (void)
  76. {
  77.     union REGS regs;
  78.  
  79.     regs.h.ah = GET_DRIVE_PARAMS;
  80.     regs.h.dl = number;
  81.     int86 (DISK_INT,®s,®s);
  82.     if ((errorcode = regs.h.ah) != 0) return;
  83.     geometry.heads = (dword) regs.h.dh + 1;
  84.     geometry.sectors = (dword) regs.h.cl & 0x3f;
  85.     geometry.cylinders = ((dword) regs.h.ch | (((dword) regs.h.cl << 2) & 0x300)) + 1;
  86. }
  87.  
  88. /* ----------------------------------------------------------------------- */
  89. /* Bios call reset_drive, returns error status in var errorcode            */
  90. /* ----------------------------------------------------------------------- */
  91.  
  92. void physical_drive::reset (void)
  93. {
  94.     union REGS regs;
  95.  
  96.     regs.h.ah = RESET_DISK;
  97.     regs.h.dl = number;
  98.     int86 (DISK_INT,®s,®s);
  99.     errorcode = regs.h.ah;
  100. }
  101.  
  102. /* ----------------------------------------------------------------------- */
  103. /* Initialization physical_drive, requires drive number.                   */
  104. /* Calls get_drive_geometry, errorcode contains return status              */
  105. /* ----------------------------------------------------------------------- */
  106.  
  107. physical_drive::physical_drive (int number)
  108. {
  109.     physical_drive::number = number;
  110.     get_geometry ();
  111. };
  112.  
  113. /* ----------------------------------------------------------------------- */
  114. /* Initialization physical_drive with physical_drive object                */
  115. /* ----------------------------------------------------------------------- */
  116.  
  117. physical_drive::physical_drive (physical_drive &pd)
  118. {
  119.     number = pd.number;
  120.     errorcode = pd.errorcode;
  121.     geometry = pd.geometry;
  122. }
  123.  
  124. /* ----------------------------------------------------------------------- */
  125. /* Overloaded assignment operator for physical drive                       */
  126. /* ----------------------------------------------------------------------- */
  127.  
  128. void physical_drive::operator= (physical_drive &pd)
  129. {
  130.     number = pd.number;
  131.     errorcode = pd.errorcode;
  132.     geometry = pd.geometry;
  133. }
  134.  
  135. /* ----------------------------------------------------------------------- */
  136. /* Read sector                                                             */
  137. /* ----------------------------------------------------------------------- */
  138.  
  139. int sector::read (physical_drive *drive,dword sector)
  140. {
  141.     physical_sector_no p (sector,drive->geometry);
  142.  
  143.     boolean done=false;
  144.     for (int i=0;i<3;i++)
  145.     {
  146.         if (!biosdisk (READ_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data))
  147.         {
  148.             done=true;
  149.             break;
  150.         }
  151.         drive->reset ();
  152.     }
  153.     if (!done) return (-1);
  154.     return 0;
  155. }
  156.  
  157. /* ----------------------------------------------------------------------- */
  158. /* Verify sector CRC                                                       */
  159. /* ----------------------------------------------------------------------- */
  160.  
  161. int verify_sector (physical_drive *drive,dword head,dword cylinder,dword sector,byte *buffer)
  162. {
  163.     if (biosdisk (VERIFY_SECTOR,drive->number,head,cylinder,sector,1,buffer)) return (-1);
  164.     return 0;
  165. }
  166.  
  167. /* ----------------------------------------------------------------------- */
  168. /* Write sector with verify                                                */
  169. /* ----------------------------------------------------------------------- */
  170.  
  171. int sector::write (physical_drive *drive,dword sector)
  172. {
  173.     physical_sector_no p (sector,drive->geometry);
  174.  
  175.     boolean done=false;
  176.     for (int i=0;i<3;i++)
  177.     {
  178.         if (!biosdisk (WRITE_SECTOR,drive->number,p.head,p.cylinder,p.sector,1,data))
  179.         {
  180.             done=true;
  181.             break;
  182.         }
  183.         drive->reset ();
  184.     }
  185.     if (!done) return (-1);
  186.     return (verify_sector (drive,p.head,p.cylinder,p.sector,data));
  187. }
  188.  
  189. /* ----------------------------------------------------------------------- */
  190. /* Bios call get_disk_type - returns 0 if drive not present.               */
  191. /* Valid drive numbers: 0 - 255, result: 1 - floppy without disk change    */
  192. /* detection, 2 - floppy with disk change detection, 3 - harddisk          */
  193. /* ----------------------------------------------------------------------- */
  194.  
  195. int get_disk_type (int drive_number)
  196. {
  197.     union REGS regs;
  198.  
  199.     regs.h.ah = GET_DISK_TYPE;
  200.     regs.h.dl = drive_number;
  201.     int86 (DISK_INT,®s,®s);
  202.     if (regs.x.cflag) return 0;
  203.     return (regs.h.ah);                     // disk type
  204. }
  205.